5 正则的扩展(ECMAScript6入门)

5.1 RegExp构造函数

与es5相比,es6RegExp函数支持第一个参数为正则表达式的同时,还能设置第二个参数,第二个参数设置的正则修饰符将会覆盖第一个参数中的正则修饰符

1
2
3
4
5
6
7
8
9
/* 构造器方式 */
let r1 = new RegExp('xzy', 'i')// 方式1(es5/es6): 第一个参数为字符串

let r2 = new RegExp(/xyz/i)// 方式2(es5/es6): 第一个参数为正则表达式

let r3 = new RegExp(/xyz/ig, 'i')// 方式3(es6):第一个参数为正则表达式,且支持第二个参数设置正则表达式修饰符

/* 正则对象(es5/es6) */
let r4 = /xyz/i

5.2 字符串的正则方法

es6中,字符串的四个与正则相关的方法全部会调用RegExp对象定义的相应方法

字符串实例方法 被调用的RegExp的方法
String.prototype.match RegExp.prototype[Symbol.match]
String.prototype.replace RegExp.prototype[Symbol.replace]
String.prototype.search RegExp.prototype[Symbol.search]
String.prototype.split RegExp.prototype[Symbol.split]

5.3 u修饰符

比较点 场景 不带u修饰符 带u修饰符
点字符(.) (字符串中)当匹配目标码点 0xFFFF 无法匹配 正确匹配
Unicode字符表示法(\u{})– 当做正则量词 正确识别–
量词({} (正则表达式中)跟在码点大于大于0xFFFF的字符后面 无法识别 正确识别为量词
预定义模式 (字符串中)当匹配目标码点 0xFFFF 无法匹配 正确匹配
i修饰符 (字符串中)当匹配目标为非规范的字符 无法匹配 正确匹配

5.4 y修饰符

粘连(sticky)修饰符:类似g修饰符,会进行全文匹配,区别在于

  • g修饰符每次都从lastIndex属性开始,从这个位置开始往后搜索,发现匹配为止
  • y修饰符每次也从lastIndex属性开始,从这个位置开始往后搜索,但要求在lastIndex指定的位置就发现匹配,否则返回 null

5.4.1 和 g 修饰符的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const s = 'aaa_aa_a'
const rg = /a+/g
const ry = /a+/y

let result
/* g 修饰符 */
console.log(rg.exec(s))// ["aaa", index: 0, input: "aaa_aa_a"]
console.log(rg.exec(s))// ["aa", index: 4, input: "aaa_aa_a"]
console.log(rg.exec(s))// ["a", index: 7, input: "aaa_aa_a"]
console.log(rg.exec(s))// null

/* y 修饰符 */
console.log(ry.exec(s))// ["aaa", index: 0, input: "aaa_aa_a"]
console.log(ry.exec(s))// null

5.4.2 从字符串提取 tokeb (词元)

说明:根据y修饰符粘连的特性,可以利用这一点敏感地识别到提取词元过程中是否有异常字符出现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
export default {
methods: {
/**
* 逐个取出字符串中的词元
* @param {RegExp} TOKEN_REGEX 正则实例
* @param {String} str 目标字符串
* @return {Array} 词元数组
*/

tokenize (TOKEN_REGEX, str) {
let result = []
let match
while (match = TOKEN_REGEX.exec(str)) {
result.push(match[1])
}
return result
}
},
ready: function (){
/** 从字符串提取 tokeb (词元) */
/* g 修饰符 */
const TOKEN_G = /\s*(\+|[0-9]+)\s*/g

console.log(this.tokenize(TOKEN_G, '3 + 4'))// ["3", "+", "4"]
console.log(this.tokenize(TOKEN_G, '3x + 4'))// ["3", "+", "4"]

/* y 修饰符 */
const TOKEN_Y = /\s*(\+|[0-9]+)\s*/y

console.log(this.tokenize(TOKEN_Y, '3 + 4'))// ["3", "+", "4"]
console.log(this.tokenize(TOKEN_Y, '3x + 4'))// ["3"]
}
}

5.5 sticky属性

RegExp.prototype.sticky:是否设置了y修饰符

1
2
const r = /hello\d/y
r.sticky // true

5.6 flags属性

RegExp.prototype.flags:返回正则表达式的修饰符

1
2
3
4
5
6
7
8
9
// ES5的source属性
// 返回正则表达式的正文
/abc/ig.source
// "abc"

// ES6的flags属性
// 返回正则表达式的修饰符
/abc/ig.flags
// 'gi'

5.7 RegExp.escape()

功能:将字符串中有特殊正则含义的字符转义掉
注意:曾被建议加入ES7,由于安全风险没被采纳

1
2
3
4
5
6
7
8
// 原始字符串
const str = 'hello. how are you?'

// escape 处理后的字符串
const regStr = this.escapeRegExp(str)// hello\. how are you\?

// 通过 escape 处理后的字符串构建正则实例
const regex = new RegExp(regStr, 'g')

5.8 后行断言

提案阶段,在ES7中加入。